#  daemonregistry.rb
#
#  This file is part of myvnet.
#
#  Copyright (C) 2008  Filipe David Borba Manana,  fdmanana@gmail.com
#
#  myvnet is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  myvnet is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with myvnet.  If not, see <http://www.gnu.org/licenses/>.


require 'singleton'


module Daemon
  
  
  # A singleton class whose purpose is to keep a list of daemons (instances of 
  # subclasses of Daemon::Generic) that will receive packets captured from the 
  # network.
  #
  # *Notes*: 
  # 
  # * It is NOT thread safe. All daemons should be registered before network
  #   packet sniffing starts.
  # * Each daemon can not be added multiple times. Daemons are distinguished by
  #   their object_id property.
  #
  class Registry
    include Singleton
    
    def initialize
      @daemons = []
    end
    
    
    # === Synopsis
    #
    #   Daemon::Registry#register(daemon)
    #
    # === Args
    #
    # A myvnet daemon, that is, an instance of a subclass of Daemon::Generic.
    #
    # === Return
    #
    # If the daemon was registered returns true, otherwise it returns false.
    #
    # === Description
    #
    # Registers a daemon (instance of a subclass of Daemon::Generic) for
    # receiving packets captured from the network. 
    #
    def register(daemon)
      unless @daemons.include? daemon
        @daemons.push daemon
        
        msg = "Daemon `#{daemon.name}' registered for the "
        msg << "simulated hosts #{daemon.addresses.inspect}."
        $log[:main].info msg
        
        return true
      end
      
      false
    end
    

    # === Synopsis
    #
    #   Daemon::Registry#unregister(daemon)
    #
    # === Args
    #
    # A myvnet daemon, that is, an instance of a subclass of Daemon::Generic.
    #
    # === Return
    #
    # The daemon given as a parameter if it was registered before, nil otherwise.
    #
    # === Description
    #
    # Unregisters a previously registered daemon. After being unregistered, a
    # daemon will not receive any more packets captured from the network.
    #
    def unregister(daemon)
      d = @daemons.delete(daemon)
      
      $log[:main].info "Daemon `#{daemon.name}' unregistered."
      
      d
    end
    
    
    # === Synopsis
    #
    #   Daemon::Registry#unregister_all
    #
    # === Return
    #
    # No value.
    #
    # === Description
    #
    # Unregisters all previously registered daemons.
    #    
    def unregister_all
      @daemons.clear
    end
    

    # === Synopsis
    #
    #   Daemon::Registry#each_daemon { |daemon| ... }
    #
    # === Return
    #
    # No value.
    #
    # === Description
    #
    # Yields each registered daemon to the given block.
    #            
    def each_daemon(&block)
      @daemons.each do |d|
        block.call d
      end
    end
    
    alias each each_daemon
    

    # === Synopsis
    #
    #   Daemon::Registry#registered_count
    #
    # === Return
    #
    # Number of registered daemons.
    #
    # === Description
    #
    # Returns the number of registered daemons.
    #                
    def registered_count
      @daemons.length
    end
        
  end
  
end